﻿using System;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Utilities;

namespace SMIL.Server.PictureLibraryExif
{
    public class Common
    {
        /// <summary>
        /// Check if the list exists in the web
        /// </summary>
        /// <param name="web"></param>
        /// <param name="listId">Guid</param>
        /// <returns></returns>
        internal static SPList GetList(SPWeb web, Guid listId)
        {
            try
            {
                SPList list = web.Lists.GetList(listId, true);
                return list;
            }
            catch (Exception ex)
            {
                WriteULSError(string.Format("Error in 'GetList' for Web '{0}' and ListId '{1}': {2}", web.Url, listId, ex));
                return null;
            }
        }

        /// <summary>
        /// checks if the feature is activated for the current spweb
        /// </summary>
        internal static bool FeatureActivated(SPWeb web, Guid featureId)
        {
            foreach (SPFeature feature in web.Features)
            {
                if (feature.DefinitionId == featureId)
                    return true;
            }

            return false;
        }

        /// <summary>
        /// write to the ULS Log (TraceSeverity = Exception)
        /// </summary>
        /// <param name="text"></param>
        internal static void WriteULSError(string text)
        {
            try
            {
                TraceProvider.RegisterTraceProvider();
                TraceProvider.WriteTrace(0, TraceProvider.TraceSeverity.Exception, Guid.Empty, "SMIL.Server.PictureLibraryExif.dll", "SMIL.Server.PictureLibraryExif", "General", text);
                TraceProvider.UnregisterTraceProvider();
            }
            catch (Exception)
            {
            }
        }

        /// <summary>
        /// write to the ULS Log (TraceSeverity = Verbose)
        /// </summary>
        /// <param name="text"></param>
        internal static void WriteULSVerbose(string text)
        {
            try
            {
                TraceProvider.RegisterTraceProvider();
                TraceProvider.WriteTrace(0, TraceProvider.TraceSeverity.Verbose, Guid.Empty, "SMIL.Server.PictureLibraryExif.dll", "SMIL.Server.PictureLibraryExif", "General", text);
                TraceProvider.UnregisterTraceProvider();
            }
            catch (Exception)
            {
            }

        }

        /// <summary>
        /// find account from WSS Administration Service
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        internal static string GetServiceName(string url)
        {
            string account = null;
            try
            {
                SPSecurity.RunWithElevatedPrivileges(delegate
                {
                    using (var site = new SPSite(url))
                    using (var rootWeb = site.RootWeb)
                    {
                        SPWebApplication webApplication = site.WebApplication;
                        SPFarm farm = webApplication.Farm;
                        SPServiceCollection services = farm.Services;

                        foreach (SPService service in services)
                        {
                            if (service.Name != "WSS_Administration") continue;

                            var identityCollection = new SPProcessIdentityCollection(service);
                            foreach (SPProcessIdentity identity in identityCollection)
                                account = identity.Username;
                        }
                        // ensure that the user exists in the rootWeb
                        rootWeb.EnsureUser(account);
                    }
                });
            }
            catch (Exception ex)
            {
                WriteULSError(string.Format("Error getting ServiceName: {0}", ex));
            }
            return account;
        }

        /// <summary>
        /// get the current user from the web. if it does not exist, add the user
        /// </summary>
        /// <param name="web"></param>
        /// <returns></returns>
        internal static SPUser GetCurrentUser(SPWeb web)
        {
            WriteULSVerbose(string.Format("Getting current user from web '{0}'", web.Url));
            if (web.CurrentUser != null)
            {
                WriteULSVerbose(string.Format("current user '{0}' found", web.CurrentUser.LoginName));
                return web.CurrentUser;
            }

            // ensure that the user is logged on
            WriteULSVerbose("Ensuring that the user is logged on");
            SPUtility.EnsureAuthentication();

            // ensure the user, if it does not exist
            using (var site = new SPSite(SPContext.Current.Site.Url, SPContext.Current.Site.SystemAccount.UserToken))
            using (SPWeb rootWeb = site.RootWeb)
            {
                bool allowUnsafeUpdate = rootWeb.AllowUnsafeUpdates;
                try
                {
                    rootWeb.AllowUnsafeUpdates = true;

                    // Get user identity name
                    string loginName = HttpContext.Current.User.Identity.Name;
                    WriteULSVerbose(string.Format("Ensuring user '{0}' on rootWeb '{1}'", loginName, rootWeb.Url));
                    SPUser currentUser = rootWeb.EnsureUser(loginName);

                    if (currentUser == null)
                        WriteULSError(string.Format("Could not get user '{0}' in web '{1}'", loginName, web.Url));
                    else
                        WriteULSVerbose(string.Format("Returning user '{0}' in web '{1}'", currentUser.LoginName, web.Url));

                    return currentUser;
                }
                finally
                {
                    rootWeb.AllowUnsafeUpdates = allowUnsafeUpdate;
                }
            }
        }

        internal static SPEventReceiverDefinition GetEventReceiver(SPEventReceiverDefinitionCollection receivers, string receiverName)
        {
            foreach (SPEventReceiverDefinition receiver in receivers)
            {
                if (receiver.Class == receiverName)
                {
                    return receiver;
                }
            }
            return null;
        }
    }
}
